﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Linq.Expressions;
using System.Data;

namespace FrameworkLib.Repository
{
    public class RepositoryBase<CTX> : IDisposable, IRepository where CTX : ObjectContext
    {
        private readonly CTX dataContext;

        //public override int SaveChanges(SaveOptions options)
        //{
        //    return base.SaveChanges(options);
        //}

        public RepositoryBase(CTX dataContext) //: base("")
        {
            this.dataContext = dataContext;
        }

        public void Save()
        {
            dataContext.SaveChanges();
        }

        //public IEnumerable<T> GetAll<T>()
        //{
        //    return dataContext.CreateObjectSet<T>();
        //}

        public IQueryable<T> Query<T>(Expression<Func<T, bool>> filter = null) where T : class
        {
            IQueryable<T> query = dataContext.CreateObjectSet<T>();
            if (filter != null)
                query = query.Where(filter);
            return query;
        }

        public T SingleOrDefault<T>(Expression<Func<T, bool>> predicate) where T : class
        {
            return dataContext.CreateObjectSet<T>().SingleOrDefault(predicate);
        }

        public void Insert<T>(T entity) where T : class
        {
            dataContext.CreateObjectSet<T>().AddObject(entity);
        }

        public void Update<T>(T entity) where T : class
        {
            ObjectStateEntry entityEntry = dataContext.ObjectStateManager.GetObjectStateEntry(entity);

            if (entityEntry.State == EntityState.Detached)
            {
                dataContext.CreateObjectSet<T>().Attach(entity);
                entityEntry.SetModified();
            }
        }

        public void Delete<T>(T entity) where T : class
        {
            dataContext.CreateObjectSet<T>().DeleteObject(entity);
        }

        public void Dispose()
        {
            this.Save();
        }
    }
}
